package uvt.map.graph.algorithm;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import org.openstreetmap.gui.jmapviewer.Coordinate;

import uvt.database.Database;
import uvt.database.SelectOperations;
import uvt.map.PositionsSettings;
import uvt.map.graph.Graph;
import uvt.map.graph.Node;
import uvt.map.graph.element.Segment;
import uvt.map.graph.element.Vehicle;
import uvt.map.graph.interfaces.FromWithOnToElement;

public class Algorithm {
	
	private Graph g;
	private ArrayList<ArrayList<FromWithOnToElement>> listRoutes;
	
	private static final double VEHICLE_DELAY = 0.5;
	
	public Algorithm() {
		g = new Graph();
		listRoutes = new ArrayList<ArrayList<FromWithOnToElement>>();
	}
		
	public ArrayList<ArrayList<FromWithOnToElement>> getListRoutes() {
		return listRoutes;
	}

	public boolean checkIfTransportationAvailable() {
		Date date = new Date();
		SimpleDateFormat ft = new SimpleDateFormat ("hh mm a");
		String time = "09 00 AM";//ft.format(date);//
		int hour = Integer.valueOf(time.split(" ")[0]) + 12;
		if(hour > 5 && hour < 24)
			return true;
		else return false;
	}
	
	public void positionVehiclesOnMap() {
		double delay = -0.5;
		ArrayList<Vehicle> newListVehicle = new ArrayList<Vehicle>();
		ArrayList<Segment> listSeg = null;
		for(Vehicle v : g.getListVehicle()) {
			delay += VEHICLE_DELAY;
			listSeg = g.getListSegmentsForRoute(v.getRoute());	
			Coordinate from = null;
			Coordinate to = null;
			Date date = new Date();
			SimpleDateFormat ft = new SimpleDateFormat ("hh mm a");
			String time = "07 04 AM";//ft.format(date);//"09 00 AM";//		    
			double minutesOfMovement = PositionCalculation.getVehicleHoursOfMovement(time) + delay;
			double remainingDistance = PositionCalculation.getVehicleDistanceTraveled(v.getSpeed(),minutesOfMovement);
			while(remainingDistance > 0) {
				for(Segment seg : listSeg) {
					double dist = PositionCalculation.distanceBetweenCoords(seg.getStart(),
																			seg.getStop());
					remainingDistance -= dist;
					from = seg.getStart();
					to = seg.getStop();
					// set nminutes till vehicle arrives
					if(remainingDistance < 0) {
						break;
					}
				}
			}
			double bearing = PositionCalculation.bearingBetweenCoords(from,to);
			Coordinate vehicleCoord = PositionCalculation.destinationCoordinate(from,
					                                                            Math.abs(remainingDistance),
					                                                            bearing);
			PositionsSettings.getInstance().addVehicleOnMap(v,vehicleCoord);
			v.setCoord(vehicleCoord);
			newListVehicle.add(v);
			listSeg.clear();
		}
		g.setListVehicle(newListVehicle);
	}
	
	public void findMostEfficientRoutes() {
		ArrayList<Node> copyListNodes = g.getListNodes();
		ArrayList<Node> startListNodes = new ArrayList<Node>();
		ArrayList<Node> arriveListNodes = new ArrayList<Node>();
		PositionsSettings pos = PositionsSettings.getInstance();
		Coordinate myPosition = new Coordinate(Double.valueOf(pos.getTxtMyPosLat().getText()),
                                               Double.valueOf(pos.getTxtMyPosLon().getText()));
		Coordinate arrivePosition = new Coordinate(Double.valueOf(pos.getTxtArrivePosLat().getText()),
                                                   Double.valueOf(pos.getTxtArrivePosLon().getText()));
		int i = 0;
		while(!copyListNodes.isEmpty() && i < 3) {
			Node start = PositionCalculation.getNearestNode(myPosition,copyListNodes);
			startListNodes.add(start);
			copyListNodes.remove(start);
		}
		i = 0;
		copyListNodes = g.getListNodes();
		while(!copyListNodes.isEmpty() && i < 3) {
			Node arrive = PositionCalculation.getNearestNode(arrivePosition,copyListNodes);
			arriveListNodes.add(arrive);
			copyListNodes.remove(arrive);
		}
		for(Node start : startListNodes) {
			for(Node arrive : arriveListNodes) {
				ArrayList<FromWithOnToElement> resultElement = new ArrayList<FromWithOnToElement>();
				FromWithOnToList roadsList = new FromWithOnToList();
				((SelectOperations)Database.getInstace()).selectRoads(roadsList);
				while(!roadsList.isEmpty() || !roadsList.getRoadsFrom(start).isEmpty()) {
					
				}
		
			}
		}
		
	}

}
